package org.longteng.security.api;

import org.longteng.core.annotation.AuthIgnore;
import org.longteng.security.Constants;
import org.longteng.security.utils.SecretKeyUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;

/**
 * 心跳接口，判断某个服务是否还可用
 * @author hymn.com
 * @date 2022/12/09 10:00:00
 */
@Slf4j
@RestController
public class HeartbeatController {

    @Value("${app.token.heart.secret:jwt}")
    private String secret;

    /**
     * 心跳接口
     * /heartbeat?t=202212101126&sign=juUV7jJRbEzy
     * @return
     * @throws InterruptedException
     */
    @GetMapping("/heartbeat")
    @AuthIgnore
    public String heartbeat(@RequestParam Map<String, String> lastMap) throws InterruptedException {
        if(log.isDebugEnabled()) {
            log.debug("心跳检测。{}", lastMap);
        }

        if(lastMap == null) {
            return "服务正常，传入参数有误。";
        }
        String timeValue = lastMap.get("t");
        String checkSign = lastMap.get("sign");
        if (log.isDebugEnabled()) {
            log.debug("心跳接口,timeValue:{},checkSign:{}, secret:{}",timeValue, checkSign, secret);
        }
        if(StringUtils.isAnyBlank(timeValue, checkSign)) {
            return "服务正常，传入参数有误。";
        }

        if (! SecretKeyUtils.verifySign(timeValue, secret, checkSign)) {
            return "服务正常，传入参数验证验证不通过。";
        }

        int onlineCount = getOnlineCount();
        String heartMsg = String.format("Service running(服务正常运行中)，onlineCount:%d", onlineCount);
        log.info(heartMsg);
        // 返回结果
        return heartMsg;
    }

    /**
     * 获取当前在线用户数
     * @return
     */
    private Integer getOnlineCount() {
        int onlineCount = 0;
        try {
            //获取countMap的迭代器
            Iterator iterator = Constants.tokenOnlineCountMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Date, Date> entry = (Map.Entry<Date, Date>) iterator.next();
                Date expiresDate = (Date) entry.getValue();
                if (expiresDate.getTime() > System.currentTimeMillis()) {
                    //过期时间大于当前时间则没有过期
                    onlineCount++;
                } else {
                    // 过期的清理
                    iterator.remove();
                }

            }
        }catch(Exception e) {
            log.error("获取当前在线用户数异常。", e);
        }
        return onlineCount;
    }

}
